// mapdata.cpp
#include "mapdata.h"
#include <fstream>
#include <QDebug>
#include <QDir>
#include <QCoreApplication>
#include <google/protobuf/util/json_util.h>
#include "global_logger.h"

// 构造函数：初始化MapData对象
// 参数 parent: 指向父对象的指针，用于建立对象的层次结构
MapData::MapData(QObject *parent) : QObject(parent) {
    LOG_INFO("MapData对象初始化完成");
}

/**
 * 加载地图数据
 * 该函数从指定的地图文件中读取数据，解析并转换为地图信息，然后通过信号发送到QML界面
 * 
 * @param mapName 地图文件的名称，用于指定要加载的地图
 */
void MapData::loadMap(const QString &mapName) {
    LOG_DEBUG("开始加载地图文件: {}", mapName.toStdString());
    //qDebug() << "Current working directory:" << QDir::currentPath();
    //QString appDir = QCoreApplication::applicationDirPath();
    //QString mapPath = appDir + "/" + mapName;

    // 打开地图文件
    std::ifstream file(mapName.toStdString(), std::ios::binary);
    if (!file) {
        LOG_ERROR("无法打开地图文件: {}", mapName.toStdString());
        return;
    }

    // 读取文件内容
    std::string jsonStr;
    std::getline(file, jsonStr);
    file.close();

    // 解析JSON格式的地图数据
    rbk::protocol::Message_Map mapMsg;
    google::protobuf::util::JsonParseOptions options;
    options.ignore_unknown_fields = true;
    
    auto status = google::protobuf::util::JsonStringToMessage(jsonStr, &mapMsg, options);
    if (!status.ok()) {
        LOG_ERROR("解析地图文件失败: {}", status.message().as_string());
        return;
    }

    LOG_DEBUG("成功解析地图数据，包含 {} 个位置点", mapMsg.normal_pos_list_size());

    // 如果地图有头部信息，则发送地图边界信息
    if (mapMsg.has_header() && mapMsg.header().has_min_pos() && mapMsg.header().has_max_pos()) {
        const auto& minPos = mapMsg.header().min_pos();
        const auto& maxPos = mapMsg.header().max_pos();
        emit mapBoundsUpdated(minPos.x(), minPos.y(), maxPos.x(), maxPos.y());
        LOG_DEBUG("发送地图边界信息: minX={}, minY={}, maxX={}, maxY={}", 
                            minPos.x(), minPos.y(), maxPos.x(), maxPos.y());
    }

    // 转换坐标数据
    QVector<QPointF> points;
    for (const auto &pos : mapMsg.normal_pos_list()) {
        points.append(QPointF(pos.x(), pos.y()));
    }
    
    // 发射信号通知QML
    emit pointsUpdated(points);
    LOG_INFO("地图数据加载完成，共加载 {} 个位置点", points.size());
}

// 获取当前所有机器人的信息列表
// 每个机器人信息包括ID、X坐标和Y坐标
QVariantList MapData::getRobots() const {
    LOG_DEBUG("获取机器人列表，当前共有 {} 个机器人", currentRobots_.size());
    QVariantList list;
    for (const auto& robot : currentRobots_) {
        QVariantMap vm;
        vm["id"] = robot.id;
        vm["x"] = robot.x;
        vm["y"] = robot.y;
        list.append(vm);
    }
    return list;
}

// 更新机器人的位置信息
// 参数 robotData 包含机器人ID、X坐标和Y坐标
void MapData::updateRobot(const QVariantMap &robotData) {
    QString robotId = robotData["robotId"].toString();
    double x = robotData["x"].toDouble();
    double y = robotData["y"].toDouble();
    
    /*LOG_DEBUG("更新机器人位置信息 - ID: {}, 位置: ({}, {})", 
                        robotId.toStdString(), x, y);*/
    
    // 查找是否已存在该机器人
    auto it = std::find_if(currentRobots_.begin(), currentRobots_.end(),
        [&](const RobotInfo& r) { return r.id == robotId; });
    
    // 更新或添加
    if (it != currentRobots_.end()) {
        it->x = robotData["x"].toDouble();
        it->y = robotData["y"].toDouble();
        /*LOG_DEBUG("更新机器人位置 - ID: {}, 位置: ({}, {})", 
                            robotId.toStdString(), x, y);*/
    } else {
        RobotInfo info{robotId, 
                      robotData["x"].toDouble(), 
                      robotData["y"].toDouble()};
        currentRobots_.append(info);
        /*LOG_DEBUG("添加新机器人 - ID: {}, 位置: ({}, {})", 
                           robotId.toStdString(), x, y);*/
    }
    emit robotsUpdated();
}